package com.pig.rpc.transmission.socket.server;

import com.pig.rpc.config.RpcServiceConfig;
import com.pig.rpc.dto.RpcReq;
import com.pig.rpc.dto.RpcResp;
import com.pig.rpc.handler.RpcReqHandler;
import com.pig.rpc.provider.ServiceProvider;
import com.pig.rpc.provider.impl.SimpleServiceProvider;
import com.pig.rpc.transmission.RpcServer;
import com.pig.rpc.util.ThreadPoolUtils;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Method;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

@Slf4j
public class SocketRpcServer implements RpcServer {

    private final int port;
    private final RpcReqHandler rpcReqHandler;
    private final ServiceProvider serviceProvider;
    private final ExecutorService executor;
    //private final ServiceProvider serviceProvider;

    public SocketRpcServer(int port) {

        this(port, new SimpleServiceProvider());
    }

    //如果你愿意传一个ServiceProvicer进来的话，那我就用你传的。如果你不传的话，我就用SimpleServiceProvider
    public SocketRpcServer(int port, ServiceProvider serviceProvider) {
        this.port = port;
        this.serviceProvider = serviceProvider;
        this.rpcReqHandler = new RpcReqHandler(serviceProvider);
        this.executor = ThreadPoolUtils.createIoIntensiveThreadPool("socket-rpc-server-0");
    }
    @Override
    public void start() {
        try(ServerSocket serverSocket = new ServerSocket(port)) {
            log.info("服务启动，端口:{}",port);

            Socket socket;
            while((socket = serverSocket.accept()) != null){
                executor.submit(new SocketReqHandler(socket,rpcReqHandler));
            }
        } catch (Exception e) {
            log.error("服务端异常");
        }
    }

    @Override
    public void publishService(RpcServiceConfig config) {
        serviceProvider.publishService(config);
    }

//    @SneakyThrows
//    private Object invoke(RpcReq rpcReq){
//        String rpcServiceName = rpcReq.rpcServiceName();
//        Object service = serviceProvider.getService(rpcServiceName);
//
//        log.debug("获取到对应服务：{}",service.getClass().getCanonicalName());
//        //使用反射调用方法
//        Method method = service.getClass().getMethod(rpcReq.getMethodName(), rpcReq.getParamTypes());
//        return method.invoke(service, rpcReq.getParams());
//    }
}
